package top.scsoul.voes.examination.service.impl;

import cn.hutool.core.io.FastByteArrayOutputStream;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.http.Header;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import top.scsoul.voes.common.constance.QuestionType;
import top.scsoul.voes.common.vo.ExcelVo;
import top.scsoul.voes.examination.convert.BeanConvert;
import top.scsoul.voes.examination.entity.QuestionBank;
import top.scsoul.voes.examination.entity.QuestionFillBlanks;
import top.scsoul.voes.examination.entity.QuestionJudgment;
import top.scsoul.voes.examination.entity.QuestionOption;
import top.scsoul.voes.examination.mapper.*;
import top.scsoul.voes.examination.service.QuestionBankService;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * (QuestionBank)表服务实现类
 *
 * @author guolei
 * @since 2021-07-23 13:10:43
 */
@Slf4j
@Transactional
@Service("questionBankService")
public class QuestionBankServiceImpl implements QuestionBankService {
    @Resource
    private QuestionBankMapper questionBankMapper;
    @Autowired
    QuestionOptionMapper questionOptionMapper;

    @Autowired
    QuestionFillBlanksMapper questionFillBlanksMapper;
    @Autowired
    QuestionJudgmentMapper questionJudgmentMapper;

    @Autowired
    TestPaperMapper testPaperMapper;
    @Autowired
    ScoreMapper scoreMapper;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public QuestionBank queryById(Integer id, boolean answer) {
        Integer type = questionBankMapper.queryTypeById(id);
        //单选题
        if (QuestionType.SINGLE_CHOICE.equals(type)) {
            log.info("单选题");
            QuestionBank questionBank = questionBankMapper.queryByIdWithOption(id);
            QuestionOption questionOption = questionBank.getQuestionOption();
            if (!answer) {
                questionOption.setRightKey(null);
                questionOption.setExplain(null);
            }
            return questionBank;
        }
        //多选题
        if (QuestionType.MULTIPLE_CHOICE.equals(type)) {
            log.info("多选题");
            QuestionBank questionBank = questionBankMapper.queryByIdWithOption(id);
            QuestionOption questionOption = questionBank.getQuestionOption();
            if (!answer) {
                questionOption.setRightKey(null);
                questionOption.setExplain(null);
            }
            return questionBank;

        }
        //填空题
        if (QuestionType.FILL_IN_THE_BLANKS.equals(type)) {
            log.info("填空题");
            QuestionBank questionBank = questionBankMapper.queryByIdWithFill(id);

            QuestionFillBlanks questionFillBlank = questionBank.getQuestionFillBlank();
            if (!answer) {
                questionFillBlank.setAnswer(null);
            }
            return questionBank;
        }
        //判断题
        if (QuestionType.JUDGE.equals(type)) {
            log.info("判断题");
            QuestionBank questionBank = questionBankMapper.queryByIdWithJudgment(id);

            if (!answer) {
                QuestionJudgment questionJudgment = questionBank.getQuestionJudgment();
                questionJudgment.setRightKey(null);
                questionJudgment.setExplain(null);
            }

            return questionBank;
        }
        //主观题目与填空题保持一致
        if (QuestionType.SUBJECTIVE.equals(type)) {
            log.info("主观题");
            QuestionBank questionBank = questionBankMapper.queryByIdWithFill(id);
            QuestionFillBlanks questionFillBlank = questionBank.getQuestionFillBlank();
            if (!answer) {
                questionFillBlank.setAnswer(null);
            }
            return questionBank;
        }

        return null;
    }

    @Override
    public QuestionBank queryById(Integer id) {
        return queryById(id, true);
    }


    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit  查询条数
     * @return 对象列表
     */
    @Override
    public List<QuestionBank> queryAllByLimit(int offset, int limit) {
        return this.questionBankMapper.queryAllByLimit(offset, limit);
    }

    /**
     * 查询多条数据
     *
     * @return 对象列表
     */
    @Override
    public PageInfo<QuestionBank> queryAll(QuestionBank questionBank, int currentPage, int pageSize) {
        PageHelper.startPage(currentPage, pageSize);
        List<QuestionBank> questionBanks = questionBankMapper.queryAll(questionBank);
        return new PageInfo<>(questionBanks);
    }

    /**
     * 新增数据
     *
     * @param questionBank 实例对象
     * @return 实例对象
     */
    @Override
    public QuestionBank insert(QuestionBank questionBank) {
        Integer type = questionBank.getType();
        //插入题库
        questionBankMapper.insert(questionBank);
        Integer primary = questionBank.getId();

        //插入答案

        //单选题
        if (QuestionType.SINGLE_CHOICE.equals(type)) {
            QuestionOption questionOption = questionBank.getQuestionOption();
            questionOption.setQuestionBankId(primary);
            questionOptionMapper.insert(questionOption);
        }
        //多选题
        if (QuestionType.MULTIPLE_CHOICE.equals(type)) {
            QuestionOption questionOption = questionBank.getQuestionOption();
            questionOption.setQuestionBankId(primary);
            questionOptionMapper.insert(questionOption);
        }
        //填空题
        if (QuestionType.FILL_IN_THE_BLANKS.equals(type)) {
            QuestionFillBlanks questionFillBlank = questionBank.getQuestionFillBlank();
            questionFillBlank.setQuestionBankId(primary);
            questionFillBlanksMapper.insert(questionFillBlank);
        }
        //判断题
        if (QuestionType.JUDGE.equals(type)) {
            QuestionJudgment questionJudgment = questionBank.getQuestionJudgment();
            questionJudgment.setQuestionBankId(primary);
            questionJudgmentMapper.insert(questionJudgment);
        }
        //主观题
        //等于填空题
        if (QuestionType.SUBJECTIVE.equals(type)) {
            QuestionFillBlanks questionFillBlank = questionBank.getQuestionFillBlank();
            questionFillBlank.setQuestionBankId(primary);
            questionFillBlanksMapper.insert(questionFillBlank);
        }
        return questionBank;
    }

    /**
     * 修改数据
     *
     * @param questionBank 实例对象
     * @return 实例对象
     */
    @Override
    public QuestionBank update(QuestionBank questionBank) {
        //题编号
        Integer id = questionBank.getId();
        //题型
        Integer type = questionBank.getType();
        //单选题
        if (QuestionType.SINGLE_CHOICE.equals(type)) {
            QuestionOption questionOption = questionBank.getQuestionOption();
            questionOption.setQuestionBankId(id);
            questionOptionMapper.update(questionOption);
        }
        //多选题
        if (QuestionType.MULTIPLE_CHOICE.equals(type)) {
            QuestionOption questionOption = questionBank.getQuestionOption();
            questionOption.setQuestionBankId(id);
            questionOptionMapper.update(questionOption);
        }
        //填空题
        if (QuestionType.FILL_IN_THE_BLANKS.equals(type)) {
            QuestionFillBlanks questionFillBlank = questionBank.getQuestionFillBlank();
            questionFillBlank.setQuestionBankId(id);
            questionFillBlanksMapper.update(questionFillBlank);
        }
        //判断题
        if (QuestionType.JUDGE.equals(type)) {
            QuestionJudgment questionJudgment = questionBank.getQuestionJudgment();
            questionJudgment.setQuestionBankId(id);
            questionJudgmentMapper.update(questionJudgment);
        }
        //主观题
        //等于填空题
        if (QuestionType.SUBJECTIVE.equals(type)) {
            QuestionFillBlanks questionFillBlank = questionBank.getQuestionFillBlank();
            questionFillBlank.setQuestionBankId(id);
            questionFillBlanksMapper.update(questionFillBlank);
        }
        questionBankMapper.update(questionBank);
        return this.queryById(questionBank.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer id) {
        //删除答卷上面的题
        testPaperMapper.deleteByQuestionBankId(id);
        scoreMapper.deleteByQuestionBankId(id);
        //先删除答案
        //再删除题
        QuestionBank questionBank = questionBankMapper.queryById(id);
        Integer type = questionBank.getType();
        //单选题
        if (QuestionType.SINGLE_CHOICE.equals(type)) {
            questionOptionMapper.deleteByQuestionBankId(id);
        }
        //多选题
        if (QuestionType.MULTIPLE_CHOICE.equals(type)) {
            questionOptionMapper.deleteByQuestionBankId(id);
        }
        //填空题
        if (QuestionType.FILL_IN_THE_BLANKS.equals(type)) {
            questionFillBlanksMapper.deleteByQuestionBankId(id);
        }
        //判断题
        if (QuestionType.JUDGE.equals(type)) {
            questionJudgmentMapper.deleteByQuestionBankId(id);
        }
        //主观题
        if (QuestionType.SUBJECTIVE.equals(type)) {
            questionFillBlanksMapper.deleteByQuestionBankId(id);
        }
        return questionBankMapper.deleteById(id) > 0;
    }

    @Override
    public boolean deleteByIds(List<Integer> ids) {
        if (ids != null && ids.size() > 0) {
            ids.forEach(id -> {
                boolean b = this.deleteById(id);
            });
        }
        return true;
    }


    @Override
    public Map<String, Long> searchCount(String keyWord) {

        Long total = questionBankMapper.searchCount(null, keyWord);
        Long singleChose = questionBankMapper.searchCount(QuestionType.SINGLE_CHOICE, keyWord);
        Long multipleChose = questionBankMapper.searchCount(QuestionType.MULTIPLE_CHOICE, keyWord);
        Long fillBlanks = questionBankMapper.searchCount(QuestionType.FILL_IN_THE_BLANKS, keyWord);
        Long judge = questionBankMapper.searchCount(QuestionType.JUDGE, keyWord);
        Long subjective = questionBankMapper.searchCount(QuestionType.SUBJECTIVE, keyWord);

        return new HashMap<String, Long>() {{
            put("total", total);
            put("singleChose", singleChose);
            put("multipleChose", multipleChose);
            put("fillBlanks", fillBlanks);
            put("judge", judge);
            put("subjective", subjective);
        }};
    }

    //todo 暂未启用
    @Override
    public void importExcel(HttpServletResponse resp) throws IOException {
        List<QuestionBank> questionBanks = questionBankMapper.queryAll(new QuestionBank());
        //todo 查找方法是错误的要重写
        List<ExcelVo> excelVos= BeanConvert.questionListToExcelVoList(questionBanks);

        resp.setContentType("application/octet-stream");
        String fileName = new String("题目.xls".getBytes(StandardCharsets.UTF_8), "ISO8859-1");
        resp.setHeader(Header.CONTENT_DISPOSITION.getValue(), "attachment;filename=" +fileName);
        OutputStream os = resp.getOutputStream();
        ExcelWriter writer = ExcelUtil.getWriter();
        writer.write(excelVos,true);
        writer.flush(os);
        writer.close();

    }

    @Override
    public Integer uploadExcel(MultipartFile file) throws IOException {
        InputStream inputStream = file.getInputStream();
        ExcelReader reader = ExcelUtil.getReader(inputStream);
        List<ExcelVo> excelVos = reader.read(1, 2, 2147483647, ExcelVo.class);
        List<QuestionBank> lists=BeanConvert.excelVoToQuestion(excelVos);
        for (QuestionBank questionBank : lists) {
            insert(questionBank);
        }
        return lists.size();
    }

    @Override
    public void getExcelModel(HttpServletResponse response) throws IOException {
        InputStream inputStream = new ClassPathResource("/static/file/用户信息导入模板.xls").getInputStream();
        OutputStream os = response.getOutputStream();

        BufferedInputStream bis = new BufferedInputStream(inputStream);
        byte[] buffer = new byte[1024];

        int len;
        while ((len=bis.read(buffer))!=-1) {
            os.write(buffer, 0, len);
        }
        IoUtil.close(bis);
        IoUtil.close(inputStream);
        IoUtil.close(os);
    }
}